重構就是『在不改變外部行為的狀況下,改變程式結構或擴充程式功能』,所以我們在調整程式結構的時候就會希望滿足以下條件
只要習慣 PHPStorm 或者是 VSCode + PHPUnit Test Explorer 的開發方式,就立刻滿足以上兩個條件了,所以希望大家要花點時間去練習上述的開發方式
接到一個 a + b = c 的需求,在得知這樣的需求後我們可以馬上寫出以下的程式碼
<?php
// tests/CalculatorTest.php
namespace Recca0120\Ithome30\Tests;
use PHPUnit\Framework\TestCase;
use Recca0120\Ithome30\Calculator;
class CalculatorTest extends TestCase
{
public function test_sum_5_3_equals_8()
{
$calculator = new Calculator();
self::assertEquals(8, $calculator->sum(5, 3));
}
}
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum($a, $b)
{
return $a + $b;
}
}
接下來又得到一個需求為 a + b + c = d 我們可以馬上寫出以下的程式碼
<?php
// tests/CalculatorTest.php
namespace Recca0120\Ithome30\Tests;
use PHPUnit\Framework\TestCase;
use Recca0120\Ithome30\Calculator;
class CalculatorTest extends TestCase
{
public function test_sum_5_3_equals_8()
{
$calculator = new Calculator();
self::assertEquals(8, $calculator->sum(5, 3));
}
public function test_sum_5_3_9_equals_8()
{
$calculator = new Calculator();
self::assertEquals(17, $calculator->sum(5, 3, 9));
}
}
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum($a, $b, $c = 0)
{
return $a + $b + $c;
}
}
接下來又得到一個需求為 a + b + c + d = e,這時我們就會覺得好煩啊,所以我們就可以把程式碼改為
<?php
// tests/CalculatorTest.php
namespace Recca0120\Ithome30\Tests;
use PHPUnit\Framework\TestCase;
use Recca0120\Ithome30\Calculator;
class CalculatorTest extends TestCase
{
public function test_sum_5_3_equals_8()
{
$calculator = new Calculator();
self::assertEquals(8, $calculator->sum(5, 3));
}
public function test_sum_5_3_9_equals_8()
{
$calculator = new Calculator();
self::assertEquals(17, $calculator->sum(5, 3, 9));
}
public function test_sum_5_3_9_4_equals_8()
{
$calculator = new Calculator();
self::assertEquals(21, $calculator->sum(5, 3, 9, 4));
}
}
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum()
{
$numbers = func_get_args();
$result = 0;
foreach ($numbers as $number) {
$result += $number;
}
return $result;
}
}
這樣就滿足了所有需求並且有所的測試都通過了,過了幾天後突然看到了Variable-length argument lists這一篇,發現這個比較好閱讀,所以我們就馬上可以把 Calculator 調整為(測試不變)
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum(...$numbers)
{
$result = 0;
foreach ($numbers as $number) {
$result += $number;
}
return $result;
}
}
又突然在某天看到了array_reduce,我們又可以把程式碼改為(修改完請立即執行一次PHPUnit)
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum(...$numbers)
{
return array_reduce($numbers, function ($carry, $number) {
return $carry + $number;
}, 0);
}
}
又突然在某天看到了Arrow Functions,我們又可以把程式碼改為(修改完請立即執行一次PHPUnit)
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum(...$numbers)
{
return array_reduce($numbers, fn ($carry, $number) => $carry + $number, 0);
}
}
又突然在某天看到了array_sum,我們又可以把程式碼改為(修改完請立即執行一次PHPUnit)
<?php
// src/Calculator.php
namespace Recca0120\Ithome30;
class Calculator
{
public function sum(...$numbers)
{
return array_sum($numbers);
}
}
雖然這是一個非常簡單的例子,但從上面的歷程來看,我們可以從只會 for 迴圈的程式新手,經過重構的過程讓我們變成程式大師並且程式碼變的容易閱讀